package fr.labri.macchiato.ui.preferences;

import java.util.ArrayList;
import java.util.List;

import com.smartgwt.client.types.Side;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.tab.Tab;
import com.smartgwt.client.widgets.tab.TabSet;

import fr.labri.macchiato.core.model.UserPreferences;
import fr.labri.macchiato.core.service.Services;
import fr.labri.macchiato.ui.ApplicationPanel;

/**
 * Class that collects all the information fulfilled in the widgets using the <a
 * href="http://c2.com/cgi/wiki?CollectingParameter" >Pattern collecting
 * parameters</a>
 * 
 * 
 * @author Michelle AVOMO
 * @author Matthieu FOUCAULT
 */
public class AllPreferences extends Window {

	private static final String Title = "Page des préférences";

	private static final String SAVE = "Enregistrer";

	private static final String CANCEL = "Annuler";

	private AddressWidget addressWidget = new AddressWidget();
	private HoursWidget hoursWidget = new HoursWidget();
	private BusinessEntityWidget providersWidget = new BusinessEntityWidget();
	private FeatureWidget featureWidget = new FeatureWidget();
	private SaveInfosWidget saveInfosWidget = new SaveInfosWidget();

	private List<PreferencesWidget> listPreferencesWidget = new ArrayList<PreferencesWidget>();

	private UserPreferences userpreferences;

	private IButton saveBtn = new IButton(SAVE);
	private IButton cancelBtn = new IButton(CANCEL);
	private HLayout buttonsLayout = new HLayout();

	/**
	 * Constructor
	 */
	public AllPreferences() {

		initPreferences();

		this.setTitle(Title);
		this.setIsModal(true);
		this.setShowModalMask(true);
		this.setAutoCenter(true);
		this.setAutoSize(true);
		this.centerInPage();
		this.setCanDragReposition(true);
		this.setCanDragResize(true);

		final TabSet tabSet = new TabSet();

		tabSet.setTabBarPosition(Side.TOP);
		tabSet.setTabBarAlign(Side.LEFT);
		tabSet.setWidth(600);
		tabSet.setHeight(350);

		tabSet.setCanEditTabTitles(false);

		addWidgetToList();
		addWidgetToTabSet(tabSet);
		addButtons();

		eventsOnClick();
		restoreUserPreferences();

		this.addItem(tabSet);
		this.addItem(buttonsLayout);
		this.show();

	}

	/************************************************* PRIVATE METHODS ********************************************************/

	/**
	 * Restores the user preferences browsing the set of widgets with non empty
	 * preferences
	 */

	private void restoreUserPreferences() {
		for (PreferencesWidget preferences : listPreferencesWidget)
			preferences.restoreUserPreferences(userpreferences);
	}

	/****
	 * Macchiato's appropriate events when the user clicks on a button 'save'
	 * and 'cancel'
	 */
	private void eventsOnClick() {
		cancelBtn.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				destroy();
			}
		});

		saveBtn.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				//Services.getInstance().initializeServiceFactory(
				//		userpreferences.getUseLocalStorage());
				for (PreferencesWidget preferences : listPreferencesWidget)
					preferences.collectUserPreferences(userpreferences);

				userpreferences.setPreferencesConfigured(true);
				initializeFactory();
				destroy();
				ApplicationPanel.initialize(new ApplicationPanel());

			}
		});
	}

	/**
	 * Creates as many tabs as objects in the list
	 * {@linkplain listPreferencesWidget}
	 * 
	 * @param tabSet
	 *            : Tabset where we add the tab with a widget for preferences
	 *            inside
	 */
	private void addWidgetToTabSet(final TabSet tabSet) {

		for (PreferencesWidget widget : listPreferencesWidget) {
			Tab widgetToDisplay = new Tab(widget.getTitle());
			widgetToDisplay.setCanClose(false);
			widgetToDisplay.setPane((Canvas) widget);
			tabSet.addTab(widgetToDisplay);
		}
	}

	/**
	 * List that contains all the widgets for preferences. NOTE: If you want to
	 * add a new Widget as a tab, just add it as a element of the list e.g :
	 * listPreferencesWidget.add(myNewWidget)
	 */
	private void addWidgetToList() {
		listPreferencesWidget.add(addressWidget);
		listPreferencesWidget.add(hoursWidget);
		listPreferencesWidget.add(providersWidget);
		listPreferencesWidget.add(featureWidget);
		listPreferencesWidget.add(saveInfosWidget);
	}

	/**
	 * Adds the buttons save and cancel to the layout
	 */
	private void addButtons() {
		buttonsLayout.setPadding(10);
		buttonsLayout.addMember(saveBtn);
		buttonsLayout.addMember(cancelBtn);
	}

	/**
	 * If the user had already given some infos and that they are stored into
	 * the cache, retrieve them. Otherwise, create a new user preference
	 */
	private void initPreferences() {
		userpreferences = Services.getInstance().getPreferencesService()
				.getUserPreferences();
		if (userpreferences == null)
			userpreferences = new UserPreferences();
	}

	/**
	 * Decides if it's a persistent or a transient factory that we have to
	 * create
	 */
	private void initializeFactory() {

		//Services.getInstance().setPreferencesService(userpreferences.getUseLocalStorage());

		Services.getInstance().getPreferencesService()
				.setUserPreferences(userpreferences);
		ApplicationPanel.initialize(new ApplicationPanel());
	}

}
